#pragma once

#include <MyControls/Doc.h>
#include <MyControls/Sequence.h>
#include <MyControls/SequenceCmdImpl.h>
#include <MyControls/Property.h>
#include <MyControls/TypedProperty.h>
#include <MyControls/StdProperties.h>
#include <typelib/fraction.h>

#include "Types.h"
#include "CXSegmentSet.h"
#include "Background.h"

class CXComp;

class SequenceCmdImpl : public My::SequenceCmdImpl
{
public:
	SequenceCmdImpl(CXComp & comp) : m_Comp(comp)
		{ }
	virtual My::Sequence * GetSequence();
private:
	CXComp & m_Comp;
};

class CXComp : 
	public CCmdTarget,
	public My::Doc, 
	public My::Sequence,
	public My::Editable<CXComp>
{
public:
	CXComp();
	~CXComp();
public:
	CXSegmentSet & GetSegments();
	Footage & GetFootage();
	FootageSPtr & GetFootageSPtr() { return m_pFootage; }
	FootageSPtr const & GetFootageSPtr() const { return m_pFootage; }
	Background & GetBackground() { return m_Background; }
public:
	fraction const & GetExportFramerate() const { return m_ExportFramerate; }
	void SetExportFramerate(fraction);
	float GetExportInaccuracy() const { return m_ExportInaccuracy; }
	void SetExportInaccuracy(float);
public:
	// My::Doc implementation
	virtual void New();
	void New(FootageSPtr);
	void Close();
	virtual void DoOpen(const String &, int);
	virtual void DoSave(const String &);
	virtual bool CanClose();
public:
	// My::Sequence implementation
	virtual bool IsEmpty() const;
	virtual int GetStart() const;
	virtual Size GetDuration() const;
	virtual Span GetWorkArea() const;
	virtual void SetWorkArea(Span);
	virtual int GetCurrentFrame() const;
	virtual void SetCurrentFrame(int);
	virtual int GetPreviewFrame() const;
	virtual void SetPreviewFrame(int);
	virtual Extent GetDim() const;
	virtual bool CanStartFollow() const;
private:
	void DoSetWorkArea(Span);
	void DoSetExportFramerate(fraction const &);
	void DoSetExportInaccuracy(float);
private:
	void Serialize(xml::stream & s, const String & sPath);
	void SetEmpty(bool);
private:
	FootageSPtr		m_pFootage;
	Background		m_Background;
	CXSegmentSet	m_Segments;
	Span			m_WorkArea;
	int				m_CurrentFrame;
	int				m_PreviewFrame;
	bool			m_Empty;
	int				m_NumRenderings;
	SequenceCmdImpl m_SequenceCmdImpl;
	fraction		m_ExportFramerate;
	float			m_ExportInaccuracy;
	friend class Renderer;
public:
	static My::Property<Span>	WorkArea;
	static My::Property<int>	CurrentFrame;
	static My::Property<fraction> ExportFramerate;
	static My::Property<float>	ExportInaccuracy;
	virtual const char * GetEditCaption() const
		{ return "Composition"; }
	static void InitPropertyMap(My::PropertyMap &);
public:
	virtual BOOL OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo);
	DECLARE_MESSAGE_MAP()
	afx_msg void OnEditClear();
	afx_msg void OnUpdateEditClear(CCmdUI *pCmdUI);
	afx_msg void OnFileExportCrispMasks();
	afx_msg void OnUpdateNotEmpty(CCmdUI *pCmdUI);
	afx_msg void OnFileExportSmoothMasks();
	afx_msg void OnFileRender();
	afx_msg void OnFileImportBackground();
};